# Model for an events site

DB = Sequel.open 'postgres://localhost/upcoming'

DB.create_table :events do
  primary_key :id
  column :title, :text
  column :title_link, :text
  column :stamp, :timestamp
  column :body, :text
  column :venue, :text
  column :city, :text
end

DB.create_table :tags do
  primary_key :id
  column :name, :text
end

DB.create_table :events_tags do
  foreign_key :event_id, :table => :events, :on_delete => :cascade
  foreign_key :tag_id, :table => :tags, :on_delete => :cascade
  index :event_id
  index :tag_id
end

class Event < Sequel::Model(:events)
  many_to_many :tags, :class => Tag, :through => :events_tags
  # implies :foreign_key => :event_id, which is qualified to :events_tags__event_id
  # implies :relation_foreign_key => Tag.primary_key = :id, qualified to :tags__id

  # tags should have the following methods:
  # add(Tag)
  # set([Tag, ...])
  # by doing:
  # tags.extend(ManyToManyHelpers)
  # tags.set
  
  def tag_names
    tags.map(:name)
  end
  
  def tag_names=(list)
    tags.set(list.map {|t| Tag.find_by_name(t)})
    # Synonymous with:
    # db.transaction do
    #   tags.delete
    #   list.map {|tag| Tag.find_by_name(tag)} do |tag|
    #     db[:event_tags] << {:event_id => id, :tag_id => tag.id}
    #   end
    # end
  end
end

class Tag < Sequel::Model(:tags)
  many_to_many :events, :class => Event, :through => :event_tags
  
  def find_by_name(name)
    name = normalize_name(name)
    dataset[:name => name] || create(:name => name)
  end
  
  def normalize_name(name)
    name.strip
  end
end